package ink.xiaobaibai.controller.onePay;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import ink.xiaobaibai.autoConfig.roleResources.ResourcesRoleMapping;
import ink.xiaobaibai.common.MyRole;
import ink.xiaobaibai.common.ReportType;
import ink.xiaobaibai.entity.AdminUser;
import ink.xiaobaibai.entity.Department;
import ink.xiaobaibai.entity.OzoneDevice;
import ink.xiaobaibai.entity.ReportClientOrder;
import ink.xiaobaibai.response.ResponseFormat;
import ink.xiaobaibai.service.IAdminUserService;
import ink.xiaobaibai.service.IDepartmentService;
import ink.xiaobaibai.service.IOzoneDeviceService;
import ink.xiaobaibai.service.IReportClientOrderService;
import ink.xiaobaibai.units.MySecurity;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * @description: 财务控制器
 * @author: 小白白
 * @create: 2021-05-23
 **/

@RestController
@RequestMapping("/onePay/finance")
@CrossOrigin
@Api(tags = "定点报表接口")
@Slf4j
@ResourcesRoleMapping(resourceName = "单次业务报表", includeRoleNames = {MyRole.ADMIN, MyRole.POWER_REPORT})
public class ReportFinanceController {

    @Autowired
    private IOzoneDeviceService ozoneDeviceService;

    @Autowired
    private IAdminUserService adminUserService;

    @Autowired
    private IReportClientOrderService reportClientOrderService;

    @Autowired
    private IDepartmentService departmentService;

    /**
     * 获取机器报表集合
     * 业务员:自己负责的
     * 经理:部门负责的
     * 上面:都可以
     */
    @GetMapping("/device/list")
    @ApiOperation("机器报表集合")
    public ResponseFormat getDeviceReportList(@RequestParam(value = "pageNum", defaultValue = "1", required = false) Integer pageNum,
                                              @RequestParam(value = "pageSize", defaultValue = "20", required = false) Integer pageSize,
                                              @RequestParam(value = "deviceCode", required = false) String deviceCode,
                                              @RequestParam(value = "time", required = false) String time) {
        String role = MySecurity.getRole();
        Set<String> roles = MySecurity.getRoles();
        Integer userId = MySecurity.getUserId();

        if (deviceCode != null) {
            /**
             * 只查机器
             * 业务员: 验证
             * 经理: 验证
             * 管理员 直接
             * 有time再加上time
             */
            QueryWrapper<OzoneDevice> q1 = new QueryWrapper<>();
            q1.select("admin_user_id");
            q1.eq("device_code", deviceCode);
            OzoneDevice ozoneDevice = this.ozoneDeviceService.getOne(q1);
            if (ozoneDevice == null) {
                return ResponseFormat.fail("库中无此机器,请输入正确的机器码");
            }

            //不包含报表角色,那么就去进行base角色过滤
            if (!roles.contains(MyRole.POWER_REPORT)) {
                if (role.equals(MyRole.DISTRIBUTOR)) {
                    //业务员
                    if (!userId.equals(ozoneDevice.getAdminUserId())) {
                        return ResponseFormat.fail("不可查看他人机器");
                    }
                } else if (role.equals(MyRole.AGENT)) {
                    //经理
                    if (!this.adminUserService.identicalDep(ozoneDevice.getAdminUserId(), userId)) {
                        //不可查看其他部门机器
                        return ResponseFormat.fail("不可查看其他部门机器");
                    }
                }
            }

            QueryWrapper<ReportClientOrder> q2 = new QueryWrapper<>();
            q2.select("id", "type", "type_id", "time", "turnover");
            q2.eq("type_id", deviceCode);
            if (time != null) {
                q2.eq("time", time);
            }
            q2.eq("type", ReportType.DEVICE.getType());
            q2.orderByDesc("time");
            Page<ReportClientOrder> page = this.reportClientOrderService.page(new Page<>(pageNum, pageSize), q2);
            return ResponseFormat.success(page);
        }

        /**
         * 需要机器码
         */
        List<String> deviceCodeList = null;
        if (!roles.contains(MyRole.POWER_REPORT)) {
            if (role.equals(MyRole.DISTRIBUTOR)) {
                //业务员所负责的所有机器码
                QueryWrapper<OzoneDevice> q1 = new QueryWrapper<>();
                q1.select("device_code");
                q1.eq("admin_user_id", MySecurity.getUserId());
                deviceCodeList = this.ozoneDeviceService.list().stream().map(OzoneDevice::getDeviceCode).collect(Collectors.toList());
            } else if (role.equals(MyRole.AGENT)) {
                //经理当前部门所有业务员所负责的机器码
                //当前部门员工的id们
                List<Integer> userIds = this.adminUserService.getDepUserIdByUserId(userId);
                //查询所有机器码
                QueryWrapper<OzoneDevice> q1 = new QueryWrapper<>();
                q1.select("device_code");
                q1.in("admin_user_id", userIds);
                deviceCodeList = this.ozoneDeviceService.list(q1).stream().map(OzoneDevice::getDeviceCode).collect(Collectors.toList());
            }
        }

        QueryWrapper<ReportClientOrder> q1 = new QueryWrapper<>();
        q1.eq("type", ReportType.DEVICE.getType());
        q1.orderByDesc("time");
        if (deviceCodeList != null) {
            //部分机器
            q1.in("type_id", deviceCodeList);
        }
        if (time != null) {
            q1.eq("time", time);
        }
        q1.select("id", "type", "type_id", "time", "turnover");
        Page<ReportClientOrder> page = this.reportClientOrderService.page(new Page<>(pageNum, pageSize), q1);
        return ResponseFormat.success(page);
    }

    /**
     * 获取个人报表集合
     * 业务员:自己的
     * 经理:部门内的
     * 上面:都可以
     */
    @GetMapping("/user/list")
    @ApiOperation("个人报表集合")
    public ResponseFormat getUserReportList(@RequestParam(value = "pageNum", defaultValue = "1", required = false) Integer pageNum,
                                            @RequestParam(value = "pageSize", defaultValue = "20", required = false) Integer pageSize,
                                            @RequestParam(value = "userId", required = false) Integer qUserId,
                                            @RequestParam(value = "time", required = false) String time) {

        String role = MySecurity.getRole();
        Set<String> roles = MySecurity.getRoles();
        Integer userId = MySecurity.getUserId();

        if (qUserId != null) {
            if (!roles.contains(MyRole.POWER_REPORT)) {
                if (role.equals(MyRole.DISTRIBUTOR)) {
                    return ResponseFormat.fail("只能查看自己的报表");
                }
                if (role.equals(MyRole.AGENT)) {
                    if (!this.adminUserService.identicalDep(qUserId, userId)) {
                        return ResponseFormat.fail("只能查看自己部门内人员报表");
                    }
                }
            }
            QueryWrapper<ReportClientOrder> q1 = new QueryWrapper<>();
            // type_id数据库中其实是user_name
            AdminUser nameAndPhone = this.adminUserService.getNameAndPhone(qUserId);
            q1.eq("type_id", nameAndPhone.getUserName());
            if (time != null) {
                q1.eq("time", time);
            }
            q1.eq("type", ReportType.PERSONAL.getType());
            q1.select("id", "type", "type_id", "time", "turnover");
            q1.orderByDesc("time");
            Page<ReportClientOrder> page = this.reportClientOrderService.page(new Page<>(pageNum, pageSize), q1);
            return ResponseFormat.success(page);
        }

        List<Integer> userIds = null;

        if (!roles.contains(MyRole.POWER_REPORT)) {
            if (role.equals(MyRole.DISTRIBUTOR)) {
                //个人
                userIds = new ArrayList<>();
                userIds.add(userId);
            } else if (role.equals(MyRole.AGENT)) {
                //加入部门内所有人
                userIds = this.adminUserService.getDepUserIdByUserId(userId);
            }
        }

        QueryWrapper<ReportClientOrder> q1 = new QueryWrapper<>();
        q1.eq("type", ReportType.PERSONAL.getType());
        q1.orderByDesc("time");
        if (userIds != null) {
            // 查询对应姓名
            QueryWrapper<AdminUser> q2 = new QueryWrapper<>();
            q2.select("user_name");
            q2.in("id", userIds);
            List<String> list = this.adminUserService.list(q2).stream().map(AdminUser::getUserName).collect(Collectors.toList());
            q1.in("type_id", list);
        }
        if (time != null) {
            q1.eq("time", time);
        }
        q1.select("id", "type", "type_id", "time", "turnover");
        return ResponseFormat.success(this.reportClientOrderService.page(new Page<>(pageNum, pageSize), q1));
    }

    /**
     * 获取部门报表集合
     * 业务员:不可
     * 经理:自己的
     * 上面:都可以
     */
    @GetMapping("/dep/list")
    @ApiOperation("部门报表集合")
    public ResponseFormat getDepReportList(@RequestParam(value = "pageNum", defaultValue = "1", required = false) Integer pageNum,
                                           @RequestParam(value = "pageSize", defaultValue = "20", required = false) Integer pageSize,
                                           @RequestParam(value = "depId", required = false) Integer depId,
                                           @RequestParam(value = "time", required = false) String time) {
        String role = MySecurity.getRole();
        Set<String> roles = MySecurity.getRoles();
        Integer userId = MySecurity.getUserId();
        if (!roles.contains(MyRole.POWER_REPORT)) {
            if (role.equals(MyRole.DISTRIBUTOR)) {
                return ResponseFormat.fail("无权限");
            }
        }
        QueryWrapper<ReportClientOrder> q1 = new QueryWrapper<>();
        q1.eq("type", ReportType.DEPARTMENT.getType());
        q1.orderByDesc("time");
        if (!roles.contains(MyRole.POWER_REPORT)) {
            if (role.equals(MyRole.AGENT)) {
                QueryWrapper<AdminUser> q0 = new QueryWrapper<>();
                q0.select("department_id");
                q0.eq("id", userId);
                AdminUser adminUser = this.adminUserService.getOne(q0);
                Integer departmentId = adminUser.getDepartmentId();
                String departmentName = this.departmentService.getById(departmentId).getDepartmentName();
                q1.in("type_id", departmentName);
                q1.select("id", "type", "type_id", "time", "turnover");
                return ResponseFormat.success(this.reportClientOrderService.page(new Page<>(pageNum, pageSize), q1));
            }
        }
        if (time != null) {
            q1.eq("time", time);
        }
        if (depId != null) {
            String departmentName = this.departmentService.getById(depId).getDepartmentName();
            q1.eq("type_id", departmentName);
        }
        q1.select("id", "type", "type_id", "time", "turnover");
        Page<ReportClientOrder> page = this.reportClientOrderService.page(new Page<>(pageNum, pageSize), q1);
        return ResponseFormat.success(page);
    }

    @GetMapping("/down/{id}")
    @ApiOperation("下载当前文件(后跟文件id)")
    public ResponseFormat downFileById(@PathVariable("id") Integer id) {
        String role = MySecurity.getRole();
        Set<String> roles = MySecurity.getRoles();
        Integer userId = MySecurity.getUserId();
        ReportClientOrder reportClientOrder = this.reportClientOrderService.getById(id);
        if (reportClientOrder == null) {
            return ResponseFormat.fail("对应报表不存在");
        }
        String type = reportClientOrder.getType();
        ReportType reportType = ReportType.getReportType(type);
        /**
         * 检验switch reportType不可能为空
         */
        switch (reportType) {
            case DEVICE:
                //机器类型文件下载
                String deviceCode = reportClientOrder.getTypeId();
                QueryWrapper<OzoneDevice> q1 = new QueryWrapper<>();
                q1.select("admin_user_id");
                q1.eq("device_code", deviceCode);
                OzoneDevice ozoneDevice = this.ozoneDeviceService.getOne(q1);
                if (ozoneDevice == null) {
                    return ResponseFormat.fail("当前机器不存在");
                }
                Integer adminUserId = ozoneDevice.getAdminUserId();
                if (!roles.contains(MyRole.POWER_REPORT)) {
                    if (role.equals(MyRole.DISTRIBUTOR) && !adminUserId.equals(userId)) {
                        return ResponseFormat.fail("不能下载他人机器");
                    }
                    if (role.equals(MyRole.AGENT) && !this.adminUserService.identicalDep(adminUserId, userId)) {
                        return ResponseFormat.fail("不能下载其它部门机器");
                    }
                }
                break;
            case PERSONAL:
                //个人类型文件下载
                // 防止重名,这里都给下载
//                QueryWrapper<AdminUser> q6 = new QueryWrapper<>();
//                q6.select("id");
//                q6.eq("user_name",reportClientOrder.getTypeId());
//                q6.last("limit 1");
//                adminUserService.getOne(q6);
//                Integer dbUserId=Integer.parseInt(reportClientOrder.getTypeId());
//                if(!roles.contains(MyRole.POWER_REPORT)) {
//                    if (role.equals(MyRole.DISTRIBUTOR) && !dbUserId.equals(userId)) {
//                        return ResponseFormat.fail("不能下载其他人的报表");
//                    }
//                    if (role.equals(MyRole.AGENT) && !adminUserService.identicalDep(userId, dbUserId)) {
//                        return ResponseFormat.fail("不能下载其他部门人员报表");
//                    }
//                }
                break;
            case DEPARTMENT:
                //部门类型报表文件下载
                // reportClientOrder.getTypeId() 其实是部门名称
                QueryWrapper<Department> q5 = new QueryWrapper<>();
                q5.eq("department_name", reportClientOrder.getTypeId());
                Department department = this.departmentService.getOne(q5);
                if (department != null) {
                    Integer depId = department.getId();
                    if (!roles.contains(MyRole.POWER_REPORT)) {
                        if (role.equals(MyRole.DISTRIBUTOR)) {
                            return ResponseFormat.fail("权限不足");
                        }
                        if (role.equals(MyRole.AGENT) && !this.adminUserService.getDepId(userId).equals(depId)) {
                            return ResponseFormat.fail("不可下载其他部门的报表");
                        }
                    }
                }
                break;
            default:
                return ResponseFormat.fail("权限不足");
        }
        String resultUrl = this.reportClientOrderService.getReportUrl(reportClientOrder.getUri());
        return ResponseFormat.success(resultUrl);
    }

}
